package com.school.sports.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.school.sports.dto.UserDTO;
import com.school.sports.entity.User;
import com.school.sports.service.UserService;
import com.school.sports.common.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.util.List;

/**
 * 用户管理控制器
 * 提供用户CRUD、批量导入、状态管理等功能
 */
@RestController
@RequestMapping("/api/users")
@Tag(name = "用户管理", description = "用户管理相关接口，包括用户查询、新增、修改、删除、状态管理等功能")
public class UserController {

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;

    /**
     * 分页查询用户列表
     * @param currentPage 当前页码
     * @param pageSize 每页大小
     * @param user 查询条件
     * @return 分页结果
     */
    @Operation(summary = "分页查询用户列表", description = "根据查询条件分页查询用户信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "查询成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "403", description = "权限不足")
    })
    @GetMapping("/page/{currentPage}/{pageSize}")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<IPage<User>> getUserPage(
            @Parameter(description = "当前页码，从1开始", required = true)
            @PathVariable("currentPage") Integer currentPage,
            @Parameter(description = "每页记录数，最大100", required = true)
            @PathVariable("pageSize") Integer pageSize,
            @Parameter(description = "查询条件，支持按用户名、真实姓名等查询")
            User user) {

        logger.info("分页查询用户列表，当前页码：{}，每页条数：{}，查询条件：{}", currentPage, pageSize, user);

        // 参数校验
        if (currentPage == null || currentPage <= 0) {
            currentPage = 1;
        }
        if (pageSize == null || pageSize <= 0) {
            pageSize = 10;
        }

        try {
            IPage<User> page = userService.getUserPage(currentPage, pageSize, user);
            logger.info("查询用户列表成功，共{}条记录", page.getTotal());
            return Result.success(page);
        } catch (Exception e) {
            logger.error("查询用户列表异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 分页查询用户信息（包含角色信息）
     * 使用优化的JOIN查询避免N+1问题
     *
     * @param currentPage 当前页码
     * @param pageSize 每页大小
     * @param realName 真实姓名（可选）
     * @param roleId 角色ID（可选）
     * @param isActive 是否激活（可选）
     * @param college 学院（可选）
     * @return 分页结果
     */
    @GetMapping("/page-with-role/{currentPage}/{pageSize}")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<IPage<UserDTO>> getUserPageWithRole(
            @PathVariable("currentPage") Integer currentPage,
            @PathVariable("pageSize") Integer pageSize,
            @RequestParam(value = "realName", required = false) String realName,
            @RequestParam(value = "roleId", required = false) Integer roleId,
            @RequestParam(value = "isActive", required = false) Boolean isActive,
            @RequestParam(value = "college", required = false) String college) {

        logger.info("分页查询用户信息（包含角色），当前页码：{}，每页条数：{}，查询条件：realName={}, roleId={}, isActive={}, college={}",
                currentPage, pageSize, realName, roleId, isActive, college);

        // 参数校验
        if (currentPage == null || currentPage <= 0) {
            currentPage = 1;
        }
        if (pageSize == null || pageSize <= 0 || pageSize > 100) {
            pageSize = 10;
        }

        try {
            Page<UserDTO> page = new Page<>(currentPage, pageSize);
            IPage<UserDTO> result = userService.getUserPageWithRole(page, realName, roleId, isActive, college);
            logger.info("查询用户信息（包含角色）成功，共{}条记录", result.getTotal());
            return Result.success(result);
        } catch (Exception e) {
            logger.error("查询用户信息（包含角色）异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 根据真实姓名模糊查询用户（包含角色信息）
     * 使用优化的索引查询
     *
     * @param realName 真实姓名
     * @param currentPage 当前页码
     * @param pageSize 每页大小
     * @return 分页结果
     */
    @GetMapping("/search-by-name")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<IPage<UserDTO>> searchUsersByRealName(
            @RequestParam("realName") String realName,
            @RequestParam(value = "currentPage", defaultValue = "1") Integer currentPage,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {

        logger.info("根据真实姓名搜索用户，姓名：{}，当前页码：{}，每页条数：{}", realName, currentPage, pageSize);

        if (realName == null || realName.trim().isEmpty()) {
            return Result.fail("真实姓名不能为空");
        }

        // 参数校验
        if (currentPage == null || currentPage <= 0) {
            currentPage = 1;
        }
        if (pageSize == null || pageSize <= 0 || pageSize > 50) {
            pageSize = 10;
        }

        try {
            Page<UserDTO> page = new Page<>(currentPage, pageSize);
            IPage<UserDTO> result = userService.searchUsersByRealName(page, realName.trim());
            logger.info("根据真实姓名搜索用户成功，共{}条记录", result.getTotal());
            return Result.success(result);
        } catch (Exception e) {
            logger.error("根据真实姓名搜索用户异常：{}", e.getMessage(), e);
            return Result.fail("搜索失败：" + e.getMessage());
        }
    }

    /**
     * 根据ID查询用户详情
     * @param userId 用户ID
     * @return 用户详情
     */
    @GetMapping("/{userId}")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<User> getUserById(@PathVariable("userId") Long userId) {
        logger.info("查询用户详情，用户ID：{}", userId);

        if (userId == null || userId <= 0) {
            return Result.fail("用户ID无效");
        }

        try {
            User user = userService.getUserById(userId);
            if (user == null) {
                return Result.fail("用户不存在");
            }
            logger.info("查询用户详情成功，用户名：{}", user.getUsername());
            return Result.success(user);
        } catch (Exception e) {
            logger.error("查询用户详情异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 新增用户
     * @param user 用户信息
     * @return 操作结果
     */
    @Operation(summary = "新增用户", description = "创建新的用户账号")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "用户创建成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "403", description = "权限不足"),
            @ApiResponse(responseCode = "409", description = "用户名已存在")
    })
    @PostMapping
    @PreAuthorize("hasRole('管理员')")
    public Result<String> addUser(
            @Parameter(description = "用户信息，包含用户名、密码、真实姓名等", required = true)
            @Valid @RequestBody User user) {
        logger.info("新增用户：{}", user.getUsername());

        try {
            // 参数校验
            if (user.getUsername().length() < 3 || user.getUsername().length() > 20) {
                return Result.fail("用户名长度必须在3-20个字符之间");
            }

            if (user.getPasswordHash() == null || user.getPasswordHash().length() < 6) {
                return Result.fail("密码长度不能少于6个字符");
            }

            // 检查用户名是否已存在
            if (userService.checkUsernameExists(user.getUsername())) {
                return Result.fail("用户名已存在");
            }

            boolean success = userService.register(user);
            if (success) {
                logger.info("新增用户成功：{}", user.getUsername());
                return Result.success("添加成功");
            } else {
                return Result.fail("添加失败");
            }
        } catch (Exception e) {
            logger.error("新增用户异常：{}", e.getMessage(), e);
            return Result.fail("添加失败：" + e.getMessage());
        }
    }

    /**
     * 更新用户信息
     * @param user 用户信息
     * @return 操作结果
     */
    @PutMapping
    @PreAuthorize("hasRole('管理员')")
    public Result<String> updateUser(@Valid @RequestBody User user) {
        logger.info("更新用户信息：{}", user.getId());

        if (user.getId() == null || user.getId() <= 0) {
            return Result.fail("用户ID无效");
        }

        try {
            // 检查用户是否存在
            User existingUser = userService.getUserById(user.getId());
            if (existingUser == null) {
                return Result.fail("用户不存在");
            }

            // 如果修改了用户名，检查新用户名是否已存在
            if (!existingUser.getUsername().equals(user.getUsername()) &&
                userService.checkUsernameExists(user.getUsername())) {
                return Result.fail("用户名已存在");
            }

            boolean success = userService.updateUser(user);
            if (success) {
                logger.info("更新用户信息成功：{}", user.getId());
                return Result.success("更新成功");
            } else {
                return Result.fail("更新失败");
            }
        } catch (Exception e) {
            logger.error("更新用户信息异常：{}", e.getMessage(), e);
            return Result.fail("更新失败：" + e.getMessage());
        }
    }

    /**
     * 删除用户
     * @param userId 用户ID
     * @return 操作结果
     */
    @DeleteMapping("/{userId}")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> deleteUser(@PathVariable("userId") Long userId) {
        logger.info("删除用户：{}", userId);

        if (userId == null || userId <= 0) {
            return Result.fail("用户ID无效");
        }

        try {
            boolean success = userService.deleteUser(userId);
            if (success) {
                logger.info("删除用户成功：{}", userId);
                return Result.success("删除成功");
            } else {
                return Result.fail("删除失败");
            }
        } catch (Exception e) {
            logger.error("删除用户异常：{}", e.getMessage(), e);
            return Result.fail("删除失败：" + e.getMessage());
        }
    }

    /**
     * 批量删除用户
     * @param userIds 用户ID列表
     * @return 操作结果
     */
    @DeleteMapping("/batch")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> batchDeleteUsers(@RequestBody List<Long> userIds) {
        logger.info("批量删除用户：{}", userIds);

        if (userIds == null || userIds.isEmpty()) {
            return Result.fail("请选择要删除的用户");
        }

        try {
            boolean success = userService.batchDeleteUsers(userIds);
            if (success) {
                logger.info("批量删除用户成功，共{}个用户", userIds.size());
                return Result.success("批量删除成功");
            } else {
                return Result.fail("批量删除失败");
            }
        } catch (Exception e) {
            logger.error("批量删除用户异常：{}", e.getMessage(), e);
            return Result.fail("批量删除失败：" + e.getMessage());
        }
    }

    /**
     * 修改用户状态
     * @param userId 用户ID
     * @param isActive 是否激活
     * @return 操作结果
     */
    @PutMapping("/{userId}/status")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> updateUserStatus(
            @PathVariable("userId") Long userId,
            @RequestParam("isActive") Boolean isActive) {

        logger.info("修改用户状态：{} -> {}", userId, isActive);

        if (userId == null || userId <= 0) {
            return Result.fail("用户ID无效");
        }

        try {
            boolean success = userService.updateUserStatus(userId, isActive);
            if (success) {
                logger.info("修改用户状态成功：{}", userId);
                return Result.success("状态修改成功");
            } else {
                return Result.fail("状态修改失败");
            }
        } catch (Exception e) {
            logger.error("修改用户状态异常：{}", e.getMessage(), e);
            return Result.fail("状态修改失败：" + e.getMessage());
        }
    }

    /**
     * 重置用户密码
     * @param userId 用户ID
     * @param newPassword 新密码
     * @return 操作结果
     */
    @PutMapping("/{userId}/password")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> resetPassword(
            @PathVariable("userId") Long userId,
            @RequestParam("newPassword") String newPassword) {

        logger.info("重置用户密码：{}", userId);

        if (userId == null || userId <= 0) {
            return Result.fail("用户ID无效");
        }

        if (newPassword == null || newPassword.length() < 6) {
            return Result.fail("新密码长度不能少于6个字符");
        }

        try {
            boolean success = userService.resetPassword(userId, newPassword);
            if (success) {
                logger.info("重置用户密码成功：{}", userId);
                return Result.success("密码重置成功");
            } else {
                return Result.fail("密码重置失败");
            }
        } catch (Exception e) {
            logger.error("重置用户密码异常：{}", e.getMessage(), e);
            return Result.fail("密码重置失败：" + e.getMessage());
        }
    }

    /**
     * 批量导入用户
     * @param file Excel文件
     * @return 导入结果
     */
    @PostMapping("/import")
    @PreAuthorize("hasRole('管理员')")
    public Result<String> importUsers(@RequestParam("file") MultipartFile file) {
        logger.info("批量导入用户，文件名：{}", file.getOriginalFilename());

        if (file.isEmpty()) {
            return Result.fail("请选择要导入的文件");
        }

        try {
            // TODO: 实现Excel解析逻辑
            // 这里暂时返回提示信息
            return Result.fail("Excel导入功能待实现");
        } catch (Exception e) {
            logger.error("批量导入用户异常：{}", e.getMessage(), e);
            return Result.fail("导入失败：" + e.getMessage());
        }
    }

    /**
     * 根据角色ID查询用户列表
     * @param roleId 角色ID
     * @return 用户列表
     */
    @GetMapping("/by-role/{roleId}")
    @PreAuthorize("hasAnyRole('管理员', '老师')")
    public Result<List<User>> getUsersByRoleId(@PathVariable("roleId") Integer roleId) {
        logger.info("根据角色ID查询用户列表，角色ID：{}", roleId);

        if (roleId == null || roleId <= 0) {
            return Result.fail("角色ID无效");
        }

        try {
            List<User> users = userService.getUsersByRoleId(roleId);
            logger.info("查询成功，共{}个用户", users.size());
            return Result.success(users);
        } catch (Exception e) {
            logger.error("根据角色ID查询用户列表异常：{}", e.getMessage(), e);
            return Result.fail("查询失败：" + e.getMessage());
        }
    }

    /**
     * 用户注册
     * @param user 用户信息
     * @return 注册结果
     */
    @PostMapping("/register")
    public Result<String> register(@Valid @RequestBody User user) {
        logger.info("用户注册：{}", user.getUsername());

        try {
            // 参数校验
            if (user.getUsername().length() < 3 || user.getUsername().length() > 20) {
                return Result.fail("用户名长度必须在3-20个字符之间");
            }

            if (user.getPasswordHash().length() < 6) {
                return Result.fail("密码长度不能少于6个字符");
            }

            boolean success = userService.register(user);
            if (success) {
                logger.info("用户注册成功：{}", user.getUsername());
                return Result.success("注册成功");
            } else {
                return Result.fail("注册失败，用户名可能已存在");
            }
        } catch (Exception e) {
            logger.error("用户注册异常：{}", e.getMessage(), e);
            return Result.fail("注册失败：" + e.getMessage());
        }
    }
}
